/*
 * Copyright (c) 2010, Nikolaus Moll
 * All rights reserved.
 */
package net.miblounge.gradecalculator.gui.widgets;

import javax.swing.event.EventListenerList;

import net.miblounge.gradecalculator.core.AbstractDataProvider;
import net.miblounge.gradecalculator.core.descriptors.CourseOfStudiesDescription;
import net.miblounge.gradecalculator.core.student.Student;
import net.miblounge.gradecalculator.guicommon.interfaces.IValidationListener;
import net.miblounge.gradecalculator.guicommon.util.StringUtil;
import net.miblounge.miglayout.qt.MigLayout;

import com.trolltech.qt.gui.QComboBox;
import com.trolltech.qt.gui.QGroupBox;
import com.trolltech.qt.gui.QLabel;
import com.trolltech.qt.gui.QLineEdit;
import com.trolltech.qt.gui.QWidget;

public class CourseSelectionWidget extends QGroupBox
{
    private final QLineEdit leName;
    private final QComboBox cbUniversity;
    private final QComboBox cbDegree;
    private final QComboBox cbCourseOfStudies;
    private final QComboBox cbSemester;
    private final Student student;

    private final EventListenerList listeners = new EventListenerList();

    public CourseSelectionWidget(final String title, final QWidget parent, final Student student)
    {
        super(title, parent); // tr("Student")

        this.student = student;

        final MigLayout layout = new MigLayout("", "[][grow, 250:250:800]", "");
        this.setLayout(layout);

        layout.addWidget(new QLabel(tr("Name:")));
        leName = new QLineEdit(this);
        leName.textEdited.connect(this, "revalidate()");
        layout.addWidget(leName, "grow, wrap");

        layout.addWidget(new QLabel(tr("University:")));
        cbUniversity = new QComboBox(this);
        cbUniversity.currentIndexChanged.connect(this, "universityChanged()");
        layout.addWidget(cbUniversity, "grow, wrap");

        layout.addWidget(new QLabel(tr("Degree:")));
        cbDegree = new QComboBox(this);
        cbDegree.currentIndexChanged.connect(this, "degreeChanged()");
        layout.addWidget(cbDegree, "grow, wrap");

        layout.addWidget(new QLabel(tr("Course of studies:")));
        cbCourseOfStudies = new QComboBox(this);
        cbCourseOfStudies.currentIndexChanged.connect(this, "courseOfStudiesChanged()");
        layout.addWidget(cbCourseOfStudies, "grow, wrap");

        layout.addWidget(new QLabel(tr("Semester:")));
        cbSemester = new QComboBox(this);
        cbSemester.currentIndexChanged.connect(this, "revalidate()");
        layout.addWidget(cbSemester, "w 100:, wrap");

        cbUniversity.addItem("");
        for (final String university : AbstractDataProvider.getInstance().getUniversities()) {
            cbUniversity.addItem(university);
        }

        leName.setText(student.getName());
        selectText(cbUniversity, student.getUniversityName());
        selectText(cbDegree, student.getDegree());
        selectText(cbCourseOfStudies, student.getCourseOfStudies());
        selectText(cbSemester, student.getSemester());

        if (parent instanceof IValidationListener) {
            addValidationListener((IValidationListener) parent);
        }
    }

    public void apply()
    {
        student.setName(leName.text());
        student.setUniversityName(cbUniversity.currentText());
        student.setDegree(cbDegree.currentText());
        student.setCourseOfStudies(cbCourseOfStudies.currentText());
        student.setSemester(cbSemester.currentText());
    }

    protected synchronized void notifyValidate()
    {
        for (final IValidationListener l : this.listeners.getListeners(IValidationListener.class)) {
            l.revalidate();
        }
    }

    public void addValidationListener(final IValidationListener listener)
    {
        this.listeners.add(IValidationListener.class, listener);
    }

    protected void universityChanged()
    {
        // save values
        final String lastDegree = cbDegree.currentText();
        final String lastCourse = cbCourseOfStudies.currentText();
        final String lastSemester = cbSemester.currentText();

        cbDegree.clear();
        cbDegree.addItem("");

        final String university = cbUniversity.currentText();

        if (university.equals("")) {
            return;
        }

        for (final String degree : AbstractDataProvider.getInstance().getDegrees(university)) {
            cbDegree.addItem(degree);
        }

        // restore values
        selectText(cbDegree, lastDegree);
        selectText(cbCourseOfStudies, lastCourse);
        selectText(cbSemester, lastSemester);
    }

    protected void degreeChanged()
    {
        final String university = cbUniversity.currentText();
        final String degree = cbDegree.currentText();

        final String lastCourse = cbCourseOfStudies.currentText();
        final String lastSemester = cbSemester.currentText();
        cbCourseOfStudies.clear();
        cbCourseOfStudies.addItem("");

        if (degree.equals("")) {
            return;
        }

        for (final String course : AbstractDataProvider.getInstance().getCourses(university, degree)) {
            cbCourseOfStudies.addItem(course);
        }
        selectText(cbCourseOfStudies, lastCourse);
        selectText(cbSemester, lastSemester);
    }

    protected void courseOfStudiesChanged()
    {
        final String university = cbUniversity.currentText();
        final String degree = cbDegree.currentText();
        final String course = cbCourseOfStudies.currentText();

        final String lastSemester = cbSemester.currentText();
        cbSemester.clear();
        cbSemester.addItem("");

        if (course.equals("")) {
            return;
        }

        for (final String semester : AbstractDataProvider.getInstance().getSemesters(university, degree, course)) {
            cbSemester.addItem(semester);
        }
        selectText(cbSemester, lastSemester);
    }

    protected void revalidate()
    {
        notifyValidate();
    }

    protected void selectText(final QComboBox box, final String text)
    {
        for (int i = 0; i < box.count(); i++) {
            if (box.itemText(i).equals(text)) {
                box.setCurrentIndex(i);
                return;
            }
        }
    }

    public boolean validate()
    {
        if (StringUtil.cleanString(leName.text()).equals("")) {
            return false;
        }

        if (cbSemester.currentText().equals("")) {
            return false;
        }

        return true;
    }

    public CourseOfStudiesDescription getCourseOfStudiesDescription()
    {
        if (cbSemester.currentText().equals("")) {
            return null;
        }

        final CourseOfStudiesDescription result = new CourseOfStudiesDescription();
        result.setCourseOfStudies(cbCourseOfStudies.currentText());
        result.setDegree(cbDegree.currentText());
        result.setUniversity(cbUniversity.currentText());
        result.setSemester(cbSemester.currentText());

        return result;
    }

}
